using System;
using System.ComponentModel;
using System.Reflection.PortableExecutable;
using System.Runtime;
using Godot;
using Godot.Collections;

public class TileMapSceneController
{
    //需要加存储数据和加载

    private TileMapBase tileMap;

    private SceneBase rootParent;

    private Array<Vector2I> ActorBeginPosList = new Array<Vector2I>();

    private TileMapSceneState NowState = TileMapSceneState.Init;
    private TileMapSceneSubState SubNowState = TileMapSceneSubState.Idle;

    private ActorBase chooseActor;



    private Array<Vector2I> pathTileData = new Array<Vector2I>();

    private Vector2 chooseActorInitPos = new Vector2();

    public TileMapSceneController(TileMapBase inTileMap, SceneBase parent)
    {
        tileMap = inTileMap;
        rootParent = parent;
        //todo 这里做一些敌人的初始化,根据配置
        EventManager.getInstance().addListener(EventType.EVENT_TILE_MAP_ACTOR_CLICK, OnActorClick);
        EventManager.getInstance().addListener(EventType.EVENT_TILE_MAP_ACTOR_MOVE, OnActorTileMapMove);
        EventManager.getInstance().addListener(EventType.EVENT_TILE_MAP_CHOOSE_ITEMLIST_ITEM_CLICK, OnChooseItemListClick);

        ChangeState(TileMapSceneState.ChooseActor, TileMapSceneSubState.Idle);
        //NowState = ;
        //SubNowState = ;

    }

    private void OnChooseItemListClick(object sender, EventParams param)
    {

        chooseActor = ActorModel.getInstance().GetFightHeroById((int)param.paramDict["actid"]);
        //挂载节点
        ChangeState(TileMapSceneState.ChooseActor, TileMapSceneSubState.ChooseNewActor);




    }


    //角色点击
    private void OnActorClick(object sender, EventParams param)
    {


        //选择点击了角色
        if (NowState == TileMapSceneState.ActorRound && SubNowState == TileMapSceneSubState.Idle)
        {
            chooseActor = (ActorBase)param.paramDict["actor"];
            if (chooseActor.actorType == ActorType.Hero)
            {
                ChangeState(TileMapSceneState.ActorRound, TileMapSceneSubState.ShowHeroMenu);
            }

        }
        else if (NowState == TileMapSceneState.EnemyRound)
        {
            //如果是敌人回合，无法打开 ，并且点击无效
        }
        else if (NowState == TileMapSceneState.ChooseActor && SubNowState == TileMapSceneSubState.Idle)
        {
            //选择人物阶段是移动角色
            chooseActor = (ActorBase)param.paramDict["actor"];

            ChangeState(NowState, TileMapSceneSubState.ChoosePutActor);

        }
        else if (NowState == TileMapSceneState.ChooseActor && SubNowState == TileMapSceneSubState.ChoosePutActor)
        {
            //当前是选择状态，再次单机是放置，要做放置检测
            ChangeState(NowState, TileMapSceneSubState.ChoosePutActorEnd);
        }
        else if (NowState == TileMapSceneState.ChooseActor && SubNowState == TileMapSceneSubState.ChooseNewActor)
        {
            ChangeState(NowState, TileMapSceneSubState.ChooseNewActorEnd);
        }
    }

    //角色移动
    private void OnActorTileMapMove(object sender, EventParams param)
    {
        pathTileData = (Array<Vector2I>)param.paramDict["pathData"];
        switch (chooseActor.actorType)
        {
            case ActorType.Hero:
                ChangeState(TileMapSceneState.ActorRound, TileMapSceneSubState.Move);
                break;
            case ActorType.Enemy:
                ChangeState(TileMapSceneState.EnemyRound, TileMapSceneSubState.Move);
                break;
            case ActorType.Npc:
                break;
        }
    }



    private void OnShowActorMenu()
    {
        System.Collections.Generic.Dictionary<string, object> param = new System.Collections.Generic.Dictionary<string, object>();
        param.Add("parent", chooseActor);
        //todo 这里可以做一些根据等级做菜单展示
        ViewManager.getInstance().open("ActorMenu", param);
    }




    private void OnShowCanPutActorArea()
    {
        //显示可以放置区域
        //TileMapUtil.SetCanPutActorArea(tileMap, ActorBeginPosList);
        //获取配置
        Array<Vector2I> list = new Array<Vector2I>() { new Vector2I(10, 2), new Vector2I(11, 2), new Vector2I(12, 2) };

        tileMap.SetCanPutActorArea(list);

        //打开选择页面
        //ViewManager.getInstance().open("ActorChooseView");
        ViewManager.getInstance().open("SettingView");

    }

    private void OnChooseCreateNewActor()
    {
        ViewManager.getInstance().close("ActorChooseView");
        if (chooseActor is not null)
        {
            chooseActor.isInScene = true;
            rootParent.AddChild(chooseActor);  //挂载到场景节点上
            ((ActorHero)chooseActor).EnableMouseFollow();  //开启移动
        }
    }

    private void OnChooseCreateNewActorEnd()
    {
        if (chooseActor is not null)
        {
            if (CheckIsCanPut())
            {

                chooseActor.Position = TileMapUtil.ChangePosToTilePos(chooseActor.Position); //转换坐标   
                ActorModel.getInstance().AddFightHero((ActorHero)chooseActor);
            }
            else
            {
                chooseActor.isInScene = false;
                rootParent.RemoveChild(chooseActor);
                ActorModel.getInstance().DeleteFightHero((ActorHero)chooseActor);

            }

            ((ActorHero)chooseActor).DisableMouseFollow();  //停止移动
            chooseActor = null;
            ChangeState(TileMapSceneState.ChooseActor);  //设置完成状态

        }
    }



    private void OnShowActorChooseMenu()
    {
        //打开角色选择菜单
    }

    private void OnShowEnemyMenu()
    {
        //打开敌人菜单
    }


    private bool CheckHeroActionIsEnd()
    {
        //所有hero状态都是wait
        bool result = true;
        var heroList = ActorModel.getInstance().GetFightHeroList();
        foreach (var hero in heroList)
        {
            if (hero.actorState != ActorState.wait)
            {
                result = false;
            }
        }

        return result;
    }

    private bool CheckEnemyActionIsEnd()
    {
        bool result = true;
        var enemyList = ActorModel.getInstance().GetEnemyList();
        foreach (var enemy in enemyList)
        {
            if (enemy.actorState != ActorState.wait)
            {
                result = false;
            }
        }

        return result;
    }

    private void OnClearScene()
    {
        if (!ViewManager.getInstance().isOpen("ActorMenu"))
        {
            ViewManager.getInstance().close("ActorMenu");
        }

        tileMap.InitMap();  //初始化tile地图

    }
    //跟随移动
    private void OnChooseActorMove()
    {
        if (chooseActor is not null)
        {
            ViewManager.getInstance().close("ActorChooseView");
            chooseActorInitPos = chooseActor.Position;
            ((ActorHero)chooseActor).EnableMouseFollow();  //开启移动
        }
    }
    //完成移动
    private void OnChooseActorEnd()
    {

        if (CheckIsCanPut())
        {
            chooseActor.Position = TileMapUtil.ChangePosToTilePos(chooseActor.Position); //转换坐标   
            chooseActor.isInScene = true;

        }
        else
        {
            chooseActor.isInScene = false;
            chooseActor.Position = chooseActorInitPos;

        }
        chooseActorInitPos = new Vector2(0, 0);
        ((ActorHero)chooseActor).DisableMouseFollow();  //关闭移动
        chooseActor = null;
        ChangeState(TileMapSceneState.ChooseActor);  //设置完成状态

    }

    private void OnFinishChoose()
    {
        //做一些后续操作
        ChangeState(TileMapSceneState.ActorRound);
    }


    //移动逻辑
    private void OnActorMove(TileMapSceneState state)
    {
        var anime = chooseActor.CreateTween();

        if (pathTileData.Count >= 2)
        {

            chooseActor.actorState = ActorState.move;

            foreach (Vector2I vec in pathTileData)
            {
                anime.TweenProperty(chooseActor, "position", new Vector2(vec.X * TileMapUtil.TileSize.X, vec.Y * TileMapUtil.TileSize.Y), 0.2f);
            }

            Action k = () =>
            {
                chooseActor.actorState = ActorState.idle;
                ChangeState(state, TileMapSceneSubState.Idle);

                anime.Kill();
            };
            anime.TweenCallback(Callable.From(k));
            chooseActor.leftMoveRange = chooseActor.leftMoveRange - pathTileData.Count;
        }
    }


    public void ChangeState(TileMapSceneState state, TileMapSceneSubState subState = TileMapSceneSubState.Idle)
    {

        switch (state)
        {
            //选择角色阶段
            case TileMapSceneState.ChooseActor:

                switch (subState)
                {
                    case TileMapSceneSubState.ChooseNewActor:
                        OnChooseCreateNewActor();
                        break;
                    case TileMapSceneSubState.ChooseNewActorEnd:
                        OnChooseCreateNewActorEnd();
                        break;
                    case TileMapSceneSubState.ChoosePutActor:
                        OnChooseActorMove();
                        break;
                    case TileMapSceneSubState.ChoosePutActorEnd:
                        OnChooseActorEnd();
                        break;
                    case TileMapSceneSubState.FInishChooseActor:

                        break;
                    default:
                        OnShowCanPutActorArea();
                        break;
                }
                break;
            case TileMapSceneState.ActorRound:
                OnClearScene();
                switch (subState)
                {
                    case TileMapSceneSubState.Move:
                        OnActorMove(state);  //移动距离
                        break;
                    case TileMapSceneSubState.Attact:
                        break;
                    case TileMapSceneSubState.ShowHeroMenu:
                        OnShowActorMenu(); // 打开
                        break;
                    default:

                        break;
                }
                break;
            case TileMapSceneState.ActorRoundEnd:
                break;
            case TileMapSceneState.EnemyRoundBegin:
                OnClearScene();
                //这里做其他AI处理
                break;
            case TileMapSceneState.EnemyRound:
                switch (subState)
                {
                    case TileMapSceneSubState.Move:
                        OnActorMove(state);  //移动距离
                        break;
                }
                break;
            case TileMapSceneState.Victory:
                break;
            case TileMapSceneState.Lose:
                break;
        }
        NowState = state;
        SubNowState = subState;

    }

    private bool CheckIsCanPut()
    {
        return true;
    }
}



public enum TileMapSceneState
{
    Init,
    //选择角色
    ChooseActor,
    //我方回合开始
    ActorRound,
    //我发回合结束
    ActorRoundEnd,
    //敌方回合开始
    EnemyRoundBegin,
    EnemyRound,
    //胜利
    Victory,
    //失败
    Lose

}


public enum TileMapSceneSubState
{
    Idle,
    ShowHeroMenu,
    //移动中
    Move,
    //攻击中
    Attact,
    //显示敌方的移动范围
    ShowEnemyRange,
    //打开人物选择菜单
    OpenActorChoose,
    //关闭人物选择菜单
    CloseActorChoose,
    //选择放置人物
    ChoosePutActor,
    ChoosePutActorEnd,
    //完成人物选择
    FInishChooseActor,
    //新创建角色（初次拖入）
    ChooseNewActor,

    ChooseNewActorEnd,

}

